#ifndef CODECNVJPEG2000_H
#define CODECNVJPEG2000_H

/**
 * @brief 单通道无符号16位图像JPEG 2000 编码器
 */
class JP2_U16C1Encoder
{
public:
    /**
     * @brief 构造函数
     * @param width  要进行JPEG2000编码的源图像宽度
     * @param height  要进行JPEG2000编码的源图像高度
     * @param cudaDevNum  使用哪个cuda gpu进行加速
     */
    JP2_U16C1Encoder(int width,int height,int cudaDevNum = 0);
    ~JP2_U16C1Encoder();

    /**
     * @brief 返回编码器是否能够正常使用
     * @return
     */
    bool isValid();

    /**
     * @brief 设置是否使用有损压缩
     * @param islossy 是否使用有损压缩
     * @return 成功返回true
     */
    bool setLossy(bool islossy = true);

    /**
     * @brief 将输入的无符号16位图像数据执行编码，成功返回true
     * @param input_buf  无符号16位图像数据
     * @param psnr   压缩前后图像峰值信号噪声比，越小压缩比越大,  0或正无穷大表示无损压缩(随机图像会出错无法压缩)
     * @return  成功返回true
     */
    bool doEncode(const void *input_buf, double psnr = 0);

    /**
     * @brief 获取编码后的输出结果缓冲区，该缓冲区属于本类，外部调用方不应释放它
     * @param size  返回缓冲的大小，如果编码失败返回0
     * @return  编码后的输出结果缓冲区,如果编码失败返回nullptr
     */
    const char * getOutputBuffer(size_t & size);

private:
    class D;
    D * m_dptr; //  内部成员变量集指针
};

class JP2_Decoder
{
public:
    /**
     * @brief JP2_Decoder  构造函数
     * @param cudaDevNum  使用哪个cuda gpu进行加速
     */
    JP2_Decoder(int cudaDevNum = 0);
    ~JP2_Decoder();

    /**
     * @brief 返回编码器是否能够正常使用
     * @return
     */
    bool isValid();

    /**
     * @brief 尝试解释经过jpeg2000编码的内存缓冲, 由调用方申请和释放
     * @param buf  内存缓冲指针
     * @param len  内存缓冲字节数
     * @return  成功返回true
     */
    bool parseEncodedBuf(const char * buf, size_t len);

    /**
     * @brief 解释成功后@ref parseEncodedBuf ,判断图像的类型是不是无符号16位单通道图像
     * @return
     */
    bool isU16C1Image();

    /**
     * @brief 获取解码后图像指定通道的尺寸信息
     * @param width  返回宽度
     * @param height  返回高度
     * @param component  指定通道
     */
    void getOutputInfo(int &width,int &height,int component=0);

    /**
     * @brief 执行解码,成功返回true
     * @return
     */
    bool doDecode();

    /**
     * @brief 获取解码后的指定通道的图像数据结果，不能释放返回的针
     * @param ressize  返回图像数据的字节数
     * @param component  指定通道
     * @return
     */
    const char * getDecodedRes(size_t & ressize,int component = 0);

private:
    class D;
    D * m_dptr; //  内部成员变量集指针
};

#endif // CODECNVJPEG2000_H
